#ifndef MEASURE618ALGBASE_H
#define MEASURE618ALGBASE_H
#include "ms618_parameterclass.h"
#include "ms618_edgedetect.h"

//#ifndef MEASUR_E618_DRAW_IMG
//#define MEASUR_E618_DRAW_IMG
//#endif

namespace MeasurE618
{
//    const string dir_edge_extraction_parameters("/home/adt/DataFile/WyData/MeasureData618/edge_extraction_parameters/");
//    const string dir_template_classifier_model( "/home/adt/DataFile/WyData/MeasureData618/template_classifier_model/");
//    const string dir_template_feature_model( "/home/adt/DataFile/WyData/MeasureData618/template_feature_model/");
//    const string dir_template_images( "/home/adt/DataFile/WyData/MeasureData618/template_images/");

    class AlgBase
    {
    public:
        AlgBase()=default;
        AlgBase(int n);
        virtual ~AlgBase();
        static void InitFunAll(const int n);
        static bool InitPath(const std::string &path);
        static bool SetTemplatePath(const std::string &path);
        static void SetStandardVal(const std::map<string, float> standardVal);

        static void SetWorkpieceInfo(const std::string &modeName,
                              const std::string &workpieceType = "");

        static bool LoadFitPara();
        static vector<std::string> LoadFiles(const QString &path, QString ext);
        static void InitStandardVal(const std::map<string, float> standardVal);
        float CalcMeasureDistance(const vector<float> &coefficient, float measureItem);

        static void setNumberOfAlg(const int n);

        /***********************************************************************
        *  @function CalcPixelAccordExpectDist
        *  @brief    根据实际的标准值、k、b、计算像素的理论值
        *  @param
        *  @return
        ***********************************************************************/
        float CalcPixelAccordExpectDist(const vector<float> &coefficient, float expectDist);

        void TemplateMatch(cv::Mat &img,ParameterClass &obj,std::vector<cv::Rect> &rangVec);
        void CoordinateTransformation(std::vector<cv::Point2f> &ptsVec, cv::Point2f &ptsIn,cv::Point2f &ptsOut);
        /***********************************************************************
        *  @function  CoordinateTransformationRelateToDot
        *  @brief     相对于原点坐标进行坐标转换
        *  @param
        *  @return
        ***********************************************************************/
        void CoordinateTransformationRelateToDot(const std::vector<cv::Point2f> &ptsVec,
                                                 const cv::Point2f &ptsIn,
                                                 cv::Point2f &ptsOut);

        inline void ImageCoordinateTransformation(std::vector<cv::Point> &ptsInVec,std::vector<cv::Rect> &rangVec)
        {
            for(auto ptr=ptsInVec.begin();ptr!=ptsInVec.end();ptr++)
            {
                ptr->x+=static_cast<int>(rangVec[0].x);
                ptr->y+=static_cast<int>(rangVec[0].y);
            }
        }
        inline void ImageCoordinateTransformation(std::vector<cv::Point2f> &ptsInVec,std::vector<cv::Rect> &rangVec)
        {
            for(auto ptr=ptsInVec.begin();ptr!=ptsInVec.end();ptr++)
            {
                ptr->x+=static_cast<float>(rangVec[0].x);
                ptr->y+=static_cast<float>(rangVec[0].y);
            }
        }
        inline void Pt2ftoPt(std::vector<cv::Point2f> &pt2fVec,std::vector<cv::Point> &ptVec)
        {
            for(auto &elem:pt2fVec)
            {
                cv::Point pt(static_cast<int>(elem.x),static_cast<int>(elem.y));
                ptVec.push_back(pt);
            }
        }
        static void clearAllflag(int i);

        /***********************************************************************
         *  @function CalcPosition
         *  @brief
         *  @param
         *  @return
        ***********************************************************************/
            float CalcPosition(const std::string &measureItemX,
                               const std::string &measureItemY,
                               const std::string &measureItemPos,
                               const std::string &prefix,
                               edgedetect &obj,
                               float expectRealDistX,
                               float expectRealDistY,
                               float predictPixelX,
                               float predictPixelY,
                               std::map<string, float> &measRes);

    public:
        static std::vector< std::shared_ptr<std::condition_variable>> cvarptrVec;
        static std::vector < std::shared_ptr<std::mutex>>             mtxptrVec;
        static std::vector< std::shared_ptr<std::condition_variable>> cvarptrfrontVec;
        static std::vector < std::shared_ptr<std::mutex>>             mtxptrfrontVec;
        static std::vector< std::shared_ptr<std::condition_variable>> cvarptrsideVec ;
        static std::vector < std::shared_ptr<std::mutex>>             mtxptrsideVec;
        static std::vector <bool>                           flagVec;
        static std::vector <bool>                           flagfrontVec;
        static std::vector <bool>                           flagsideVec;
        static std::map<string, float>                      m_standardValMap          ;

    protected:
        static std::vector<std::vector<Point2f>> datumBackVec;
        static std::vector<std::vector<Point2f>> datumFrontVec;
        static std::vector<std::vector<Point2f>> datumSideVec;
        static once_flag                         m_flag;
        static std::vector<ParameterClass>       m_dataAllVec;

        static once_flag               m_setStandardValOnceFlag         ;
        static std::string             m_dir_edge_extraction_parameters ;
        static std::string             m_dir_template_classifier_model  ;
        static std::string             m_dir_template_feature_model     ;
        static std::string             m_dir_template_images            ;

        static string                  m_dir_distance_fitting_model     ;
        static std::map<std::string, std::vector<float>> m_phypixpara   ;
        static bool                    m_isSetWorkpieceInfo             ;
        static bool                    m_isLoadXml                      ;
        static string                  m_modeName                       ;
        static string                  m_xmlFileNamePre                 ;

    };
}

#endif // MEASURE618ALGBASE_H
